package cn.xiaopengstack.domain.strategy.service.rule.filter.factory;

import cn.xiaopengstack.domain.strategy.model.entity.RuleActionEntity;
import cn.xiaopengstack.domain.strategy.service.annotation.LogicStrategy;
import cn.xiaopengstack.domain.strategy.service.rule.filter.ILogicFilter;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author jiangyangang
 */
@Component
@Slf4j
public class DefaultLogicFactory {

    protected Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();

    /**
     * 规则初始化
     * @param iogicFilterList
     */
    public DefaultLogicFactory(List<ILogicFilter<?>> iogicFilterList) {
        iogicFilterList.forEach((logicFilter) -> {
            LogicStrategy annotation = AnnotationUtils.findAnnotation(logicFilter.getClass(), LogicStrategy.class);
            if (Objects.isNull(annotation)) {
                return;
            }
            logicFilterMap.put(annotation.value().code, logicFilter);
        });
    }

    /**
     * 开放所有的奖励规则
     * @return
     * @param <T>
     */
    public <T extends RuleActionEntity.RaffleEntity> Map<String, ILogicFilter<T>> openLogicFilter(){
        // 二次强转，Map<String, ILogicFilter<?>> -> Map<?, ?> -> Map<String, ILogicFilter<T>>
        return (Map<String, ILogicFilter<T>>) (Map<?, ?>) logicFilterMap;
    }

    @Getter
    @AllArgsConstructor
    public enum LogicModel{
        RULE_WIGHT("rule_weight", "【抽奖前规则】根据抽奖权重返回可抽奖范围KEY", "before"),
        RULE_BLACKLIST("rule_blacklist", "【抽奖前规则】黑名单规则过滤，命中黑名单则直接返回", "before"),
        RULE_LOCK("rule_lock", "【抽奖中规则】抽奖n次后，对应奖品可解锁抽奖", "center"),
        RULE_LUCK_AWARD("rule_luck_award", "【抽奖后规则】抽奖n次后，对应奖品可解锁抽奖", "after"),
        ;

        private final String code;
        private final String info;
        private final String type;

        public static boolean isCenter(String code){
            return "center".equals(LogicModel.valueOf(code.toUpperCase()).type);
        }

        public static boolean isAfter(String code){
            return "after".equals(LogicModel.valueOf(code.toUpperCase()).type);
        }

    }
}
